function data = gcpick()
% main function
CONFIG=gcpick_config();
status.num = 0;
status.saveflag=0;
status.amp = 10;
status.cut = [-Inf, Inf];
status.cmdqueue = {};
status.waveComponent = 'ENZ';
status.waveWindow = figure('Name', 'Wave', ...
    'Position',CONFIG.wavePosition, ...
    'MenuBar', 'figure', 'ToolBar', 'auto');
status.waveWindow.GraphicsSmoothing = 'off';
status.stationWindow = figure('Name', 'Station', ...
    'Position', CONFIG.staPosition, ...
    'MenuBar', 'figure', 'ToolBar', 'auto');
while 1
    % auto save
    if status.saveflag > CONFIG.autosavestep
        if CONFIG.autosave && exist('data', 'var')
            save([CONFIG.resultpath,'/.picked_waves.mat'],'data');
            status.saveflag = 0;
            disp([CONFIG.infoIndent, 'autsaved.']);
        elseif CONFIG.autosave && ~exist('data', 'var')
            
        else
            disp([CONFIG.infoIndent, 'Remember to save!!']);
        end
    end
    % display prompt
    if exist('data', 'var') && status.num>0
        prompt = sprintf('[%s]-->', data(status.num).station);
    elseif exist('data', 'var')
        prompt = '[none]-->';
    else
        prompt = '[DATA NOT LOADED]-->';
    end
    % multicommands
    if isempty(status.cmdqueue)
        inputs = input(prompt, 's');
        inputs = strtrim(inputs);
        status.cmdqueue = strsplit(inputs, ';', 'CollapseDelimiters', true);
    end
    if length(status.cmdqueue)>=2
        inputs = status.cmdqueue{1};
        status.cmdqueue = status.cmdqueue(2:end);
    else
        inputs = status.cmdqueue{1};
        status.cmdqueue = {};
    end
    % command process
    inputs = strtrim(inputs);
    inputs = strsplit(inputs, {',', ' '}, 'CollapseDelimiters', true);
    cmd = inputs{1};
    if length(inputs)>1
        options = inputs(2:end);
    else
        options = {'',''};
    end
    if length(options)<2
        options = [ options, {''} ];
    end
    switch cmd
        case {'p', 'plot', 'print'}
            switch options{1}
                case {'s', 'station'}
                    gcpick_plotstation(data, status, CONFIG);
                case {'w', 'wave'}
                    gcpick_flushwave(data, status, CONFIG);
                case {'src', 'source'}
                    CONFIG.lon=str2double(options{2});
                    CONFIG.lat=str2double(options{3});
                    gcpick_plotstation(data, status, CONFIG);
                case {'i', 'info'}
                    if status.num<=0
                        disp([CONFIG.infoIndent, 'Station not selected.']);
                        continue;
                    end
                    gcpick_printinfo(options(2:end), data(status.num), ...
                        CONFIG, status);
                case {'sl', 'stationlist'}
                    gcpick_liststations(data, options);
                otherwise
                    disp([CONFIG.infoIndent, CONFIG.nocmdinfo]);
            end
        case {'s', 'set'}
            switch options{1}
                case {'s', 'station'}
                    if length(options)<2
                        disp([CONFIG.infoIndent, 'No station name']);
                        continue;
                    elseif ~isnan(str2double( options{2} ))
                        status.num = str2double( options{2} );
                    else
                        status.num = gcpick_choosestation(data, options{2});
                    end
                case {'x', 'xlim'}
                    gcpick_changelimit();
                case 'path'
                    CONFIG.datapath=options{2};
                    CONFIG.resultpath=CONFIG.datapath;
                case {'f', 'flag'}
                    if str2double(options{2})==1 || str2double(options{2})==0
                        data(status.num).flag = str2double(options{2});
                        xl=get(gca,'XLim');
                        yl=get(gca,'YLim');
                        gcpick_flushwave(data, status, CONFIG);
                        set(gca,'XLim',xl, 'YLim', yl);
                    else
                        disp([CONFIG.infoIndent, 'Illigal flag.']);
                    end
                case 'component'
                    if ismember(options{2}, {'E','N','Z','EN','EZ','NZ','ENZ'})
                        status.waveComponent = options{2};
                    else
                        disp([CONFIG.infoIndent, 'Setting illegal.']);
                    end
                case {'amplitude', 'A'}
                    status.amp = str2double(options{2});
                    xl=get(gca,'XLim');
                    yl=get(gca,'YLim');
                    gcpick_flushwave(data, status, CONFIG);
                    set(gca,'XLim',xl, 'YLim', yl);
                otherwise
                    disp([CONFIG.infoIndent, CONFIG.nocmdinfo]);
                    continue;
            end
        case {'g', 'get'}
            switch options{1}
                case {'t', 'arrivaltime'}
                    switch options{2}
                        case 'p'
                            data(status.num).tp=gcpick_picktime();
                        case 's'
                            data(status.num).ts=gcpick_picktime();
                        otherwise
                            disp([CONFIG.infoIndent, CONFIG.nocmdinfo]);
                    end
                case {'p', 'polarity'}
                    data(status.num).polar=gcpick_pickpolar(options);
                otherwise
                    disp([CONFIG.infoIndent, CONFIG.nocmdinfo]);
                    continue;
            end
            xl=get(gca,'XLim');
            yl=get(gca,'YLim');
            gcpick_flushwave(data, status, CONFIG);
            set(gca,'XLim',xl, 'YLim', yl);
        case {'reset', 'r'}
            if exist('data', 'var') && status.num>0
                switch options{1}
                    case {'data', 'd'}
                        data(status.num).tp = -1;
                        data(status.num).ts = -1;
                        data(status.num).flag = 0;
                        data(status.num).polar.E = 0;
                        data(status.num).polar.N = 0;
                        data(status.num).polar.Z = 0;
                    case {'setting', 'config', 's'}
                        status.amp = 10;
                        status.cut = [-Inf, Inf];
                    case 'all'
                        status.cmdqueue = [ status.cmdqueue, 'reset data', ...
                            'reset setting' ];
                    otherwise
                        disp([CONFIG.infoIndent, CONFIG.nocmdinfo]);  
                end
            else
                disp([CONFIG.infoIndent, 'no change']);
            end
        case {'rm', 'rmean'}
            if exist('data','var')
                data = gcpick_removemean(data, status);
                disp([CONFIG.infoIndent, 'mean removed.' ]);
            else
                disp([CONFIG.infoIndent, 'data not loaded.']);
                continue;
            end
        case {'rtr', 'rtrend'}
            if exist('data','var')
                data = gcpick_removetrend(data);
                disp([ CONFIG.infoIndent, 'linear trend removed' ]);
            else
                disp([CONFIG.infoIndent, 'data not loaded.']);
                continue;
            end
        case 'filt'
            if exist('data','var')
                data = gcpick_filtwave(data, options, CONFIG);
                disp([ CONFIG.infoIndent, 'filted' ]);
            else
                disp([CONFIG.infoIndent, 'data not loaded.']);
                continue;
            end
        case 'save'
            switch options{1}
                case {'','mat'}
                    if exist('data', 'var')
                        save([CONFIG.resultpath,'/.picked_waves.mat'],'data');
                        status.saveflag = 0;
                    else
                        disp([CONFIG.infoIndent, 'data not loaded.']);
                    end
                case 'excel'
                    gcpick_writetoxlsx(data, CONFIG);
                case 'nlloc'
                    gcpick_writetonllocobs(data,CONFIG);
                otherwise
                    disp([CONFIG.infoIndent, CONFIG.nocmdinfo]);
                    continue;
            end
        case 'load'
            switch options{1}
                case {'', 'mat'}
                    if exist([CONFIG.resultpath,'/.picked_waves.mat'],'file')
                        load([CONFIG.resultpath,'/.picked_waves.mat'],'data');
                    else
                        disp([CONFIG.infoIndent, 'No data file.']);
                    end
                case 'sac'
                    if exist([CONFIG.resultpath,'/.picked_waves.mat'], 'file')
                        fprintf(['>>> There is a data file for this program,\n>>> continue reading?[Y|n]\n',...
                            '>>> (reload will overwrite the datafile)\n']);
                        t = input( '>>>', 's');
                        switch t
                            case 'Y'
                                data = gcpick_loadsacdata(CONFIG);
                            case 'n'
                                load([CONFIG.resultpath,'/.picked_waves.mat'],'data');
                            otherwise
                                disp([CONFIG.infoIndent, 'No data loaded.']);
                        end
                    else
                        data = gcpick_loadsacdata(CONFIG);
                    end
                otherwise
                    disp([CONFIG.infoIndent, CONFIG.nocmdinfo]);
                    continue;
            end
        case 'help'
            gcpick_cmdhelp(options{1});
        case 'clc'
            clc;
        case 'cut'
            if exist('data', 'var')
                status.cut = str2double(options);
            end
        case {'quit', 'exit'}
            if exist('data', 'var')
                save([CONFIG.resultpath,'/.picked_waves.mat'],'data');
                disp([CONFIG.infoIndent, 'autosaved.'])
            else
                data = 'no data';
            end
            close(status.waveWindow);
            close(status.stationWindow);
            break;
        otherwise
            disp([CONFIG.infoIndent, CONFIG.nocmdinfo]);
            continue;
    end
    status.saveflag = status.saveflag + 1;
end
end